package com.ak.cluster;

import java.util.ArrayList;
import java.util.List;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.physics.box2d.Body;
import com.badlogic.gdx.physics.box2d.BodyDef;
import com.badlogic.gdx.physics.box2d.PolygonShape;
import com.badlogic.gdx.physics.box2d.World;
import com.badlogic.gdx.physics.box2d.BodyDef.BodyType;

public class GameWorld
{
	public List<GameObject> worldObjects = new ArrayList<GameObject>();
	public List<GameObject> staticObjects = new ArrayList<GameObject>();
	public ArrayList<Body> bodyList = new ArrayList<Body>();
	public OrthographicCamera worldCamera;
	public World pWorld;
	static int residualTime = 0;

	public GameWorld(OrthographicCamera cam)
	{
		worldCamera = cam;
		initPhysics();
	}

	public void addObject(GameObject o){worldObjects.add(o);}


	private void initPhysics()
	{
		pWorld = new World(new Vector2(0,-10),true);
	}

	public void createWorld()
	{
		int tracer = 0;
		for (GameObject O: worldObjects)
		{

			if(O.chosenBodyType != 3)
			{


				BodyDef bodyDef = new BodyDef();
				PolygonShape polyShape = new PolygonShape(); // creating new polyShape
				// creating new bodydef
				 //setting box size
				bodyDef.position.set(O.position); // setting position of poly def x
				polyShape.setAsBox((O.assetTexture.getWidth()*0.05f)*(O.scale.x), (O.assetTexture.getHeight()*0.05f)*(O.scale.y));

				switch(O.chosenBodyType) // begin switch statement object body type
				{
				case 0:
					bodyDef.type = BodyType.StaticBody;
					break;
				case 1:
					bodyDef.type = BodyType.DynamicBody;	// if the case is 1 = body type dynamic
					break;
				}
				bodyList.add(pWorld.createBody(bodyDef));  // creating body in local world as bodyDef
				bodyList.get(tracer).createFixture(polyShape, 10); // creating fixture and passing in shape and density
				bodyList.get(tracer).setUserData(O); // applying O to body user data
				O.objectBody = bodyList.get(tracer);
				polyShape.dispose(); // destroying shape
//
				tracer++;
			}
			else
			{
				staticObjects.add(O);
			}
//
		}
	}

	public void update(float deltatime)
	{

		//Fixed Time Step

		//End Fixed Time Step

		for(GameObject gO: worldObjects)
		{
			gO.update();
		}
		for(GameObject sO: staticObjects)
		{
			sO.update();
		}
	}
	public List<GameObject> getObjects()
	{
		return worldObjects;
	}
	
	public void dispose()
	{
		
		removeAll();
		pWorld.dispose();
		
	}
	
	public void removeAll()
	{
		for(GameObject gO: worldObjects)
		{
			gO.dispose();
			gO.objectBody = null;
			gO = null;
		}
		for(GameObject sO: staticObjects)
		{
			sO.dispose();
			sO.objectBody = null;
			sO = null;
		}
	}
	
	public void removeAllByObject(GameObject o){while(worldObjects.contains(o)){worldObjects.remove(o);}}

//	public <T> void removeObject(T t)
//	{
//		List<GameObject> tempList = worldObjects;
//
//		Comparator<T> objectFinder = new Comparator<T>()
//		{
//			@Override
//			public int compare(T o1, T o2) {
//				// TODO Auto-generated method stub
//				if(o1.equals(o2))
//				{
//					return 1;
//				}
//				return 0;
//			}
//		};
//		Collections.sort(tempList, objectFinder);
//	}

}